package com.zhang.zxx.boot.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.lang.reflect.Method;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * AsyncConfig:注入线程池
 *
 * @author zhangxiaoxiang
 * @since 2023/6/6
 */
@Configuration
@EnableAsync
@Slf4j
public class AsyncConfig {

    int cpuCoreNum = Runtime.getRuntime().availableProcessors();
    public final int CORE_POOL_SIZE = cpuCoreNum + 1;
    public final int MAX_POOL_SIZE = cpuCoreNum * 2;

    @Bean("analysisExecutor")
    public ThreadPoolTaskExecutor sendSmsExecutor() {
        // 如果不是超时异常,那么把队内多堆一点(太多也会OOM),根据实际测试
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(CORE_POOL_SIZE);
        executor.setMaxPoolSize(MAX_POOL_SIZE);
        executor.setQueueCapacity(50);
        executor.setThreadNamePrefix("------call");
        // 这里是对这个线程池的空闲线程(setMaxPoolSize-setCorePoolSize)回收时间,
        // 对全局的Tomcat的关不了(tomcat的需要单独配置,默认是60秒哈)
        executor.setKeepAliveSeconds(2);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        // executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
        // 当线程池中的数量等于最大线程数时，重试添加当前的任务；它会自动重复调用execute()方法。
        // executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // executor.setRejectedExecutionHandler((r, executor1) -> log.warn("丢弃任务"));
        executor.initialize();
        // 6核CPU
        log.info("当前CPU核心数:{},呼叫线程池,配置线程核心数:{},最大线程数:{}",cpuCoreNum,CORE_POOL_SIZE,MAX_POOL_SIZE);
        return executor;
    }
//     如果是超时,堆积少一点的队列,多了的任务直接抛弃




}
